/**
 * @description 监听dom变化 接口可以监听到 Element 的内容区域或 SVGElement的边界框改变。内容区域则需要减去内边距padding
 * @src https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver#browser_compatibility
 * @example <div v-resize="handleResize">text</div> 如果v-resize="resize或者Resize" 不会走自定义指令 没有找到原因 踩坑2小时
 * @author 曾小晖
 * @mail eggadmin2021.136.com
 * @weixin badiweier
 * @creatDate 2021/5/22
 * @version 1.0
*/
/**
 * 如果只想在视图改变时监听 可以参考 components/Echart/index.vue 组件 使用一个变量来判断 如果整个element 都没有完成事件 就用延迟函数setTimeout
 * */
// 是否支持原生resize observer
const supportResizeObserver = () => {
  return window.ResizeObserver && isFunction(window.ResizeObserver)
}
// 是否是函数
const isFunction = v => Object.prototype.toString.call(v) === '[object Function]'
/**
 * 监听dom变化
 * @param {*} el element
 * @param {Boolean} isWatch 是否开启监听
 * @param {function} callBack 回调
 * @param delayTime {number} 抖动延迟时间 根据业务可微调 默认800
 * @return {*}
 */
const resizeObserverCallback = (el, isWatch, callBack, delayTime) => {
  if (!supportResizeObserver()) {
    console.log('浏览器不支持ResizeObserver 请升级最新版', 'color:red')
    return
  }
  // observe() 方法用于观察一个指定Element 或 SVGElement
  // disconnect() 方法会停止和取消目标对象上所有对Element 或 SVGElement 的监听。
  let setTime = null
  const resizeObserver = new ResizeObserver(entries => {
    for (const entry of entries) {
      // console.log(entry.contentRect.width)
      // console.log(entry.contentRect)
      // console.log('resize')
      if (setTime) clearTimeout(setTime)
      setTime = setTimeout(() => {
        entry.contentRect.msg = '监听完成'
        callBack(entry.contentRect)
      }, delayTime)
    }
  })
  if (isWatch) {
    resizeObserver.observe(el)
  } else {
    resizeObserver.disconnect(el)
    callBack({ msg: '销毁完成' })
  }
}
export default {
  install: (app, options) => {
    // 抖动延迟时间 根据业务可微调
    let delayTime = 800
    if(options && options.delayTime) {
      delayTime = options.delayTime
    }
    app.directive('resize', {
      mounted(el, binding) {
        // console.log('mounted')
        resizeObserverCallback(el, true, binding.value, delayTime)
      },
      updated(el, binding) {
        // console.log('updated')
        resizeObserverCallback(el, true, binding.value, delayTime)
      },
      unmounted(el, binding) {
        // console.log('unmounted')
        resizeObserverCallback(el, false, binding.value, delayTime)
      }
    })
  }
}
